home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / os_dgux.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  5.6 KB  |  268 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. /*
  23.  *   Data General DG/UX support
  24.  *
  25.  *   Contributing author: Karl Owen
  26.  *   E-mail: owen@dg-rtp.dg.com
  27.  *
  28.  *   This software fragment contains code that interfaces the CD player
  29.  *   application to the Data General DG/UX operating system.  The name
  30.  *   "Data General" and DG/UX are used here for identification purposes
  31.  *   only.
  32.  */
  33. #ifndef LINT
  34. static char *_os_dgux_c_ident_ = "@(#)os_dgux.c    5.6 94/12/28";
  35. #endif
  36.  
  37. #include "common.d/appenv.h"
  38. #include "common.d/util.h"
  39. #include "libdi.d/libdi.h"
  40. #include "libdi.d/scsipt.h"
  41.  
  42.  
  43. #if defined(DGUX) && defined(DI_SCSIPT) && !defined(DEMO_ONLY)
  44.  
  45. extern appdata_t    app_data;
  46. extern bool_t        scsipt_notrom_error;
  47. extern FILE        *errfp;
  48.  
  49. STATIC int        pthru_fd = -1;    /* Passthrough device file desc */
  50.  
  51.  
  52. /*
  53.  * pthru_send
  54.  *    Build SCSI CDB and send command to the device.
  55.  *
  56.  * Args:
  57.  *    opcode - SCSI command opcode
  58.  *    addr - The "address" portion of the SCSI CDB
  59.  *    buf - Pointer to data buffer
  60.  *    size - Number of bytes to transfer
  61.  *    rsvd - The "reserved" portion of the SCSI CDB
  62.  *    length - The "length" portion of the SCSI CDB
  63.  *    param - The "param" portion of the SCSI CDB
  64.  *    control - The "control" portion of the SCSI CDB
  65.  *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  66.  *    prnerr - Whether an error message should be displayed
  67.  *         when a command fails
  68.  *
  69.  * Return:
  70.  *    TRUE - command completed successfully
  71.  *    FALSE - command failed
  72.  */
  73. bool_t
  74. pthru_send(
  75.     byte_t        opcode,
  76.     word32_t    addr,
  77.     byte_t        *buf,
  78.     word32_t    size,
  79.     byte_t        rsvd,
  80.     word32_t    length,
  81.     byte_t        param,
  82.     byte_t        control,
  83.     byte_t        rw,
  84.     bool_t        prnerr
  85. )
  86. {
  87.     byte_t                cdb[12];
  88.     struct user_scsi_param_blk    param_blk;
  89.  
  90.  
  91.     if (pthru_fd < 0 || scsipt_notrom_error)
  92.         return FALSE;
  93.  
  94.     memset(&cdb, 0, sizeof(cdb));
  95.     memset(¶m_blk, 0, sizeof(param_blk));
  96.  
  97.     /* set up SCSI CDB */
  98.     switch (opcode & 0xf0) {
  99.     case 0xa0:
  100.     case 0xe0:
  101.         /* 12-byte commands */
  102.         cdb[0] = opcode;
  103.         cdb[1] = param;
  104.         cdb[2] = (addr >> 24) & 0xff;
  105.         cdb[3] = (addr >> 16) & 0xff;
  106.         cdb[4] = (addr >> 8) & 0xff;
  107.         cdb[5] = (addr & 0xff);
  108.         cdb[6] = (length >> 24) & 0xff;
  109.         cdb[7] = (length >> 16) & 0xff;
  110.         cdb[8] = (length >> 8) & 0xff;
  111.         cdb[9] = length & 0xff;
  112.         cdb[10] = rsvd;
  113.         cdb[11] = control;
  114.  
  115.         param_blk.cdb_size = 12;
  116.         break;
  117.  
  118.     case 0xc0:
  119.     case 0xd0:
  120.     case 0x20:
  121.     case 0x30:
  122.     case 0x40:
  123.         /* 10-byte commands */
  124.         cdb[0] = opcode;
  125.         cdb[1] = param;
  126.         cdb[2] = (addr >> 24) & 0xff;
  127.         cdb[3] = (addr >> 16) & 0xff;
  128.         cdb[4] = (addr >> 8) & 0xff;
  129.         cdb[5] = addr & 0xff;
  130.         cdb[6] = rsvd;
  131.         cdb[7] = (length >> 8) & 0xff;
  132.         cdb[8] = length & 0xff;
  133.         cdb[9] = control;
  134.  
  135.         param_blk.cdb_size = 10;
  136.         break;
  137.  
  138.     case 0x00:
  139.     case 0x10:
  140.         /* 6-byte commands */
  141.         cdb[0] = opcode;
  142.         cdb[1] = param;
  143.         cdb[2] = (addr >> 8) & 0xff;
  144.         cdb[3] = addr & 0xff;
  145.         cdb[4] = length & 0xff;
  146.         cdb[5] = control;
  147.  
  148.         param_blk.cdb_size = 6;
  149.         break;
  150.  
  151.     default:
  152.         if (app_data.scsierr_msg && prnerr)
  153.             fprintf(errfp, "0x%02x: Unknown SCSI opcode\n",
  154.                 opcode);
  155.         return FALSE;
  156.     }
  157.  
  158.     DBGDUMP("SCSI CDB bytes", cdb, param_blk.cdb_size);
  159.  
  160.     param_blk.cdb_ptr = (union user_scsi_cdb *)(void *) cdb;
  161.     param_blk.data_size = size;
  162.     param_blk.data_ptr = buf;
  163.     param_blk.flags.data_write = (WRITE_OP == rw);
  164.  
  165.         if (ioctl(pthru_fd, USER_SCSI_CMD, ¶m_blk) < 0) {
  166.         if (app_data.scsierr_msg && prnerr) {
  167.             perror("USER_SCSI_CMD ioctl failed");
  168.             extended_perror("USER_SCSI_CMD ioctl failed");
  169.         }
  170.                 return FALSE;
  171.         }
  172.  
  173.         if (param_blk.scsi_status != USER_SCSI_STATUS_GOOD) {
  174.         if (app_data.scsierr_msg && prnerr) {
  175.             fprintf(errfp,
  176.                 "CD audio: %s %s:\n%s=0x%x %s=0x%x\n",
  177.                 "SCSI command fault on",
  178.                 app_data.device,
  179.                 "Opcode",
  180.                 opcode,
  181.                 "Status",
  182.                 param_blk.scsi_status);
  183.         }
  184.         return FALSE;
  185.         }
  186.  
  187.     return TRUE;
  188. }
  189.  
  190.  
  191. /*
  192.  * pthru_open
  193.  *    Open SCSI pass-through device
  194.  *
  195.  * Args:
  196.  *    path - device path name string
  197.  *
  198.  * Return:
  199.  *    TRUE - open successful
  200.  *    FALSE - open failed
  201.  */
  202. bool_t
  203. pthru_open(char *path)
  204. {
  205.     struct stat    stbuf;
  206.     char        errstr[ERR_BUF_SZ];
  207.  
  208.     /* Check for validity of device node */
  209.     if (stat(path, &stbuf) < 0) {
  210.         sprintf(errstr, app_data.str_staterr, path);
  211.         cd_fatal_popup(app_data.str_fatal, errstr);
  212.         return FALSE;
  213.     }
  214.  
  215.     if (!S_ISCHR(stbuf.st_mode)) {
  216.         sprintf(errstr, app_data.str_noderr, path);
  217.         cd_fatal_popup(app_data.str_fatal, errstr);
  218.         return FALSE;
  219.     }
  220.  
  221.     if ((pthru_fd = open(path, O_RDONLY)) < 0) {
  222.         DBGPRN(errfp, "Cannot open %s: errno=%d\n", path, errno);
  223.         return FALSE;
  224.     }
  225.  
  226.     return TRUE;
  227. }
  228.  
  229.  
  230. /*
  231.  * pthru_close
  232.  *    Close SCSI pass-through device
  233.  *
  234.  * Args:
  235.  *    Nothing.
  236.  *
  237.  * Return:
  238.  *    Nothing.
  239.  */
  240. void
  241. pthru_close(void)
  242. {
  243.     if (pthru_fd >= 0) {
  244.         close(pthru_fd);
  245.         pthru_fd = -1;
  246.     }
  247. }
  248.  
  249.  
  250. /*
  251.  * pthru_vers
  252.  *    Return OS Interface Module version string
  253.  *
  254.  * Args:
  255.  *    Nothing.
  256.  *
  257.  * Return:
  258.  *    Module version text string.
  259.  */
  260. char *
  261. pthru_vers(void)
  262. {
  263.     return ("OS Interface module (for Data General DG/UX)\n");
  264. }
  265.  
  266. #endif /* DGUX DI_SCSIPT DEMO_ONLY */
  267.  
  268.